using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using Microsoft.VisualStudio.Tools.Applications;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using System.IO;
using System.Windows.Forms;

//http://www.codeproject.com/Articles/19560/Launching-Your-Application-After-Install-using-Vis
namespace OffLine.Installer
{
    // Taken from:http://msdn2.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx
    // Set 'RunInstaller' attribute to true.
    [RunInstaller(true)]
    public class InstallerClass : System.Configuration.Install.Installer
    {
        //================================================================================================================//
        //================================================================================================================//
        static readonly Guid SolutionID = new Guid("4fc997eb-e268-418a-b762-a02b7d679915");
        public InstallerClass()
            : base()
        {
            // Attach the 'Committed' event.
            this.Committed += new InstallEventHandler(MyInstaller_Committed);
            // Attach the 'Committing' event.
            this.Committing += new InstallEventHandler(MyInstaller_Committing);

        }
        //================================================================================================================//
        //================================================================================================================//
        // Override the 'Install' method.
        public override void Install(IDictionary stateSaver)
        {
            string[] nonpublicCachedDataMembers = null;

            Uri deploymentManifestLocation = null;
            if (Uri.TryCreate(
                Context.Parameters["deploymentManifestLocation"],
                UriKind.RelativeOrAbsolute,
                out deploymentManifestLocation) == false)
            {
                throw new InstallException(
                    "The location of the deployment manifest " +
                    "is missing or invalid.");
            }

            string documentLocation =
                Context.Parameters["documentLocation"];
            if (String.IsNullOrEmpty(documentLocation))
            {
                throw new InstallException(
                    "The location of the document is missing.");
            }
            string assemblyLocation =
                Context.Parameters["assemblyLocation"];
            if (String.IsNullOrEmpty(assemblyLocation))
            {
                throw new InstallException(
                    "The location of the assembly is missing.");
            }

            string targetLocation = CreateTargetLocation(documentLocation);
            // Check if FILE Exist & busy ...
            if (File.Exists(targetLocation))
            {
                int tryno = 3;
                while (FileInUse(targetLocation) & tryno > 0)
                {
                    DialogResult res = MessageBox.Show(string.Format("This file is in use : \"{0}\"\r\nPlease close first to continue the Installation !", targetLocation), "Cannot COPY file !");
                    if (res == DialogResult.OK) if (!FileInUse(targetLocation)) break;
                    tryno--;
                }
                if (tryno == 0) throw new Exception(string.Format("Cannot Overwrite this Farpac : \"{0}\" !\r\nTry 3 times already, file still in use !", targetLocation));
            }

            // Copy Target File to Deliver Location
            File.Copy(documentLocation, targetLocation, true);
            if (ServerDocument.IsCustomized(targetLocation))
            {
                ServerDocument.RemoveCustomization(targetLocation);
            }
            ServerDocument.AddCustomization(
                targetLocation,
                assemblyLocation,
                SolutionID,
                deploymentManifestLocation,
                true,
                out nonpublicCachedDataMembers);
            stateSaver.Add("targetLocation", targetLocation);

            base.Install(stateSaver);
        }
        //================================================================================================================//
        //================================================================================================================//
        // Override the 'Commit' method.
        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
        }
        // Event handler for 'Committing' event.
        private void MyInstaller_Committing(object sender, InstallEventArgs e)
        {
            //Console.WriteLine("");
            //Console.WriteLine("Committing Event occured.");
            //Console.WriteLine("");
        }
        // Event handler for 'Committed' event.
        private void MyInstaller_Committed(object sender, InstallEventArgs e)
        {

            //Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            //Process.Start(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\InstallExample.exe");
            string targetLocation = (string)e.SavedState["targetLocation"];

            if (String.IsNullOrEmpty(targetLocation))
            {
                throw new InstallException(
                    "The location of the document is missing.");
            }

            DialogResult res = MessageBox.Show("\"New FARPAC file\" successfully install to \"DESKTOP\" Main Screen.\r\n\r\n" +
                "Do you want to open New Farpac file ? (Y/N)", "New FARPAC in DESKTOP ready to use", MessageBoxButtons.YesNo);
            try
            {
                if (res == DialogResult.Yes) System.Diagnostics.Process.Start(targetLocation);
                else if (res == DialogResult.No) System.Diagnostics.Process.Start("explorer.exe", "/select," + targetLocation);
            }
            catch
            {
                // Do nothing... 
            }
        }
        //================================================================================================================//
        //================================================================================================================//
        // Override the 'Rollback' method.
        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }
        //================================================================================================================//
        //================================================================================================================//
        // Override the 'Uninstall' method.
        public override void Uninstall(IDictionary savedState)
        {
            string targetLocation = (string)savedState["targetLocation"];
            if (String.IsNullOrEmpty(targetLocation) == false)
            {
                try { File.Delete(targetLocation); }
                catch { }
            }
            base.Uninstall(savedState);
        }
        //================================================================================================================//
        //================================================================================================================//
        static bool FileInUse(string path)
        {
            try
            {
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                }
                return false;
            }
            catch (IOException ex)
            {
                return true;
            }
        }
        string CreateTargetLocation(string documentLocation)
        {
            string fileName = Path.GetFileName(documentLocation);
            string myDocuments = Environment.GetFolderPath(
                Environment.SpecialFolder.Desktop); // Change HERE if you want to move to DESKTOP
            return Path.Combine(myDocuments, fileName);
        }
        //================================================================================================================//
        //================================================================================================================//
    }

}